using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Mvc;

namespace CookieTempData.Controllers
{
    public class CacheAndCookieTempDataProvider : ITempDataProvider
    {
        private const string keyName = "__TempData";
        private const string cookieName = "__TempDataId";
        public IDictionary<string, object> LoadTempData(
            ControllerContext controllerContext)
        {
            string cacheKey = GetCacheKey(controllerContext.HttpContext);
            Dictionary<string, object> tempData =
                controllerContext.HttpContext.Cache[cacheKey]
                as Dictionary<string, object>;
            if (tempData != null)
            {
                controllerContext.HttpContext.Cache.Remove(keyName);
                return tempData;
            }
            return new Dictionary<string, object>();
        }

        public void SaveTempData(ControllerContext controllerContext,
            IDictionary<string, object> values)
        {
            string cacheKey = GetCacheKey(controllerContext.HttpContext);
            controllerContext.HttpContext.Cache.Insert(cacheKey, values);
        }

        private string GetCacheKey(HttpContextBase httpContext)
        {
            string uniqueIdentifier = GetUniqueIdentifier(httpContext);
            return String.Format("{0}[{1}]", keyName, uniqueIdentifier);
        }

        private string GetUniqueIdentifier(HttpContextBase context)
        {
            var uniqueIdCookie = context.Request.Cookies.Get(cookieName);
            if (uniqueIdCookie == null)
            {
                uniqueIdCookie = new HttpCookie(cookieName);
                uniqueIdCookie.Value = Guid.NewGuid().ToString();
                context.Response.Cookies.Add(uniqueIdCookie);
            }
            return uniqueIdCookie.Value;
        }
    }
}